package org.snail.common.dingding.auth;

import com.alibaba.fastjson.JSONObject;
import com.dingtalk.oapi.lib.aes.DingTalkJsApiSingnature;
import com.dingtalk.open.client.ServiceFactory;
import com.dingtalk.open.client.api.service.corp.CorpConnectionService;
import org.apache.log4j.Logger;
import org.snail.common.dingding.cache.AuthCache;
import org.snail.common.dingding.exception.OApiException;
import org.snail.constant.CacheNameConstant;
import org.snail.common.dingding.Env;
import org.snail.exception.BaseException;

import java.util.Map;


/**
 */
public class AuthHelper {
    public static final Logger LOGGER = Logger.getLogger(AuthHelper.class);

    // 调整到1小时50分钟
    public static final long cacheTime = 1000 * 60 * 55 * 2;

    /*
     * 在此方法中，为了避免频繁获取access_token，
     * 在距离上一次获取access_token时间在两个小时之内的情况，
     * 将直接从持久化存储中读取access_token
     *
     * 因为access_token和jsapi_ticket的过期时间都是7200秒
     * 所以在获取access_token的同时也去获取了jsapi_ticket
     * 注：jsapi_ticket是在前端页面JSAPI做权限验证配置的时候需要使用的
     * 具体信息请查看开发者文档--权限验证配置
     */
    public static String getAccessToken() throws OApiException, BaseException {
        long curTime = System.currentTimeMillis();
        long beginTime = 0;
        String accToken = "";
        Map accessTokenMap = AuthCache.getAccesstoken(Env.ACCESSTOKEN_KEY);
        if (null != accessTokenMap && !accessTokenMap.isEmpty()) {
            try {
                beginTime = (long)accessTokenMap.get(CacheNameConstant.BEGIN_TIME);
                accToken = (String) accessTokenMap.get(CacheNameConstant.TOKEN_KEY);
            } catch (ClassCastException e) {
                LOGGER.error("redis查找token后出现类型转换错误！", e);
            }

        }
        JSONObject jsontemp = new JSONObject();
        if (accessTokenMap == null || curTime - beginTime >= cacheTime) {
            try {
                ServiceFactory serviceFactory = ServiceFactory.getInstance();
                CorpConnectionService corpConnectionService = serviceFactory.getOpenService(CorpConnectionService.class);
                accToken = corpConnectionService.getCorpToken(Env.CORP_ID, Env.CORP_SECRET);

                jsontemp.clear();
                jsontemp.put("access_token", accToken);
                jsontemp.put("begin_time", curTime);
                //真实项目中最好保存到数据库中
                AuthCache.setAccesstoken(Env.ACCESSTOKEN_KEY, jsontemp);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return accToken;
    }


    public static String sign(String ticket, String nonceStr, long timeStamp, String url) throws OApiException {
        try {
            return DingTalkJsApiSingnature.getJsApiSingnature(url, nonceStr, timeStamp, ticket);
        } catch (Exception ex) {
            throw new OApiException(0, ex.getMessage());
        }
    }

}
